package com.dkts.oil.util;

import com.alibaba.fastjson.JSONObject;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;

import java.math.BigDecimal;


/**
 * geo 面积工具类
 *
 * @author heguanglong
 */
public class GeoAreaUtil  {

    /**
     * 计算多边形的面积
     * 返回平方米
     * @param coords
     * @return
     */
    public static double signedArea(Coordinate[] coords)
    {
        Coordinate p1;
        Coordinate p2;
        Coordinate p3;
        int lowerIndex;
        int middleIndex;
        int upperIndex;
        int i;
        double total = 0;
        int coordsLength = coords.length;
        if (coordsLength > 2) {
            for (i = 0; i < coordsLength; i++) {
                if (i == coordsLength - 2) {
                    // i = N-2
                    lowerIndex = coordsLength - 2;
                    middleIndex = coordsLength - 1;
                    upperIndex = 0;
                }
                else if (i == coordsLength - 1) {
                    // i = N-1
                    lowerIndex = coordsLength - 1;
                    middleIndex = 0;
                    upperIndex = 1;
                }
                else {
                    // i = 0 to N-3
                    lowerIndex = i;
                    middleIndex = i + 1;
                    upperIndex = i + 2;
                }
                p1 = coords[lowerIndex];
                p2 = coords[middleIndex];
                p3 = coords[upperIndex];
                total += (TrackMileageUtil.rad(p3.x) - TrackMileageUtil.rad(p1.x)) * Math.sin(TrackMileageUtil.rad(p2.y));
            }
            total = (total * TrackMileageUtil.EARTH_RADIUS * TrackMileageUtil.EARTH_RADIUS) / 2;
        }
        return new BigDecimal(total).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
    }





    public static class Size {
        public double width;
        public double height;

        public Size(double width, double height) {
            this.width = width;
            this.height = height;
        }

        @Override
        public String toString() {
            return String.format("Width: %.2f m, Height: %.2f m", width, height);
        }
    }

    /**
     * 根据面积和长宽比计算矩形的长宽（单位：米）
     *
     * @param area 面积，单位：平方米
     * @param ratioW 长边比例
     * @param ratioH 宽边比例
     */
    public static Size calculateSizeByArea(double area, double ratioW, double ratioH) {
        if (area <= 0 || ratioW <= 0 || ratioH <= 0) return new Size(0, 0);

        // 假设 w = ratioW * x, h = ratioH * x => area = w * h = (ratioW * x) * (ratioH * x) = ratioW * ratioH * x^2
        double ratioProduct = ratioW * ratioH;
        double x = Math.sqrt(area / ratioProduct);

        double width = ratioW * x;
        double height = ratioH * x;

        return new Size(width, height);
    }

    public static double calculateSizeByArea(double area) {
      return  Math.sqrt(area);
    }

    // WGS84 (或者 GCJ02，如果你坐标是GCJ02） → EPSG:3857（米单位）
    public static double[] calculateAreaInSquareMeters(Geometry geometry) {
        double[] area = new double[2];
        try {

            // 定义源和目标坐标参考系
            CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:4326", true);   // GCJ02近似处理为WGS84
            CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:3857", true);   // 投影坐标系（单位：米）
            // 坐标转换器
            MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
            // 执行坐标转换
            Geometry projectedGeometry = JTS.transform(geometry, transform);
            // 返回面积（平方米） 保留两位小数
            area[0]= new BigDecimal(projectedGeometry.getArea()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
            area[1]= new BigDecimal(projectedGeometry.getLength()).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
        } catch (Exception e) {
            e.printStackTrace();
            area[0]= 0;
            area[1]= 0;
        }
        return area;
    }

}
